Skip to content

Quote version script symbols - #158607

Open
syrel wants to merge 2 commits into
rust-lang:mainfrom
syrel:quote-version-script-symbols
Open

Quote version script symbols#158607
syrel wants to merge 2 commits into
rust-lang:mainfrom
syrel:quote-version-script-symbols

Conversation

@syrel

@syrel syrel commented Jun 30, 2026

Copy link
Copy Markdown

Hi

rustc generates an LD version script in the following format:

{
  global:
    exported_symbol;
    some$foo::bar$thing/path.rs:42;

  local:
    *;
};

However, the symbols are not quoted, which means that the following code will cause a linker failure because the gnerated LD version script has an invalid syntax.

#[unsafe(export_name = "some$foo::bar$thing/path.rs:42")]
pub extern "C" fn exported_symbol_with_version_script_special_characters() {}
error: linking with `cc` failed: exit status: 1
  |
  = note:  "cc" "-Wl,--version-script=/project/target/release/deps/rustcYQww7z/list" "-Wl,--no-undefined-version" "/project/target/release/deps/rustcYQww7z/symbols.o" ...
  = note: /project/target/release/deps/rustcYQww7z/list:349: ignoring invalid character `/' in script
          /usr/bin/ld:/project/target/release/deps/rustcYQww7z/list:349: syntax error in VERSION script
          clang: error: linker command failed with exit code 1 (use -v to see invocation)

Special characters such as $, /, ., and : are valid for a symbol name in an ELF binary. LD Script Format documentation specifies (same rules apply for symbols and file names):

If the file name contains a character such as a comma which would otherwise serve to separate file names, you may put the file name in double quotes.

This PR quotes each symbol name before adding it to the global: section. This allows exported symbols containing linker-special characters, such as $, ::, /, ., and :, to be handled correctly by the linker:

{
  global:
    "exported_symbol";
    "some$foo::bar$thing/path.rs:42";

  local:
    *;
};

The new run-make test builds a cdylib with an export_name containing those characters and verifies that the exact symbol is exported from the produced shared object.

Cheers
Alex

Fixes #38238

@rustbot rustbot added A-run-make Area: port run-make Makefiles to rmake.rs S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 30, 2026
@rustbot

rustbot commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the pull request, and welcome! The Rust Project is excited to review your changes, and you should hear from @TaKO8Ki (or someone else) some time within the next two weeks.

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue
Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 73 candidates
  • Random selection from 17 candidates

Comment thread compiler/rustc_codegen_ssa/src/back/linker.rs Outdated
@bjorn3

bjorn3 commented Jun 30, 2026

Copy link
Copy Markdown
Member

Can you check if this fixes #38238?

@syrel

syrel commented Jun 30, 2026

Copy link
Copy Markdown
Author

Can you check if this fixes #38238?

Thanks for referencing the issue! This PR does indeed fix it. Just a comment about trailing spaces in export_name: even though they will be supported on linux, macos strips whitespaces. It might be wise to extend the docs around export_name and link_name to mention platform specific quirks.

@syrel
syrel requested a review from bjorn3 June 30, 2026 12:33
@rust-bors

This comment has been minimized.

@syrel
syrel force-pushed the quote-version-script-symbols branch from 8775157 to db6d1ab Compare July 6, 2026 09:21
@rustbot

rustbot commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Some changes occurred in src/tools/cargo

cc @ehuss

@rustbot rustbot added the A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. label Jul 6, 2026
@rustbot

rustbot commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@rustbot

This comment has been minimized.

@syrel
syrel force-pushed the quote-version-script-symbols branch from db6d1ab to 6f7a111 Compare July 6, 2026 09:27
@syrel

syrel commented Jul 6, 2026

Copy link
Copy Markdown
Author

Hi
I have updated the PR to be based on the recent compiler changes.
@rustbot review

@bjorn3 bjorn3 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with two minor improvements to the test.

r? bjorn3

View changes since this review

let contents = rfs::read(dynamic_lib_name("lib"));
let object = object::File::parse(contents.as_slice()).unwrap();
let matching_exports =
object.exports().unwrap().iter().filter(|x| x.name() == EXPORTED_SYMBOL).count();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Instead of .filter().count() this could also be .any(). No need to assert there is exactly one symbol with this name. There can't be multiple exported symbols with the same name anyway.

#![crate_type = "cdylib"]

#[unsafe(export_name = "some$foo::bar$thing/path.rs:42")]
pub extern "C" fn exported_symbol_with_version_script_special_characters() {}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also add a function with bad_∢ as symbol name as test for #38238? It is possible that a linker does support arbitrary printable ascii characters, but not unicode characters.

@rustbot rustbot assigned bjorn3 and unassigned TaKO8Ki Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. A-run-make Area: port run-make Makefiles to rmake.rs S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

export_name with unusual utf8 breaks new version script based linker

4 participants